//*********************************************************
//
//    Copyright (c) Microsoft. All rights reserved.
//    This code is licensed under the Apache License, Version 2.0.
//    THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
//    ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
//    IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
//    PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************

namespace Microsoft.Research.DataLayer.ServiceModel
{
    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Globalization;

    /// <summary>
    /// The category model.
    /// </summary>
    [Serializable]
    public class LeftPaneModel : BaseModel
    {
        private Collection<LeftPaneModel> children = new Collection<LeftPaneModel>();
        private bool isCategoryModel;
        private DateTime modifiedTime;
        private string versionLabel;

        /// <summary>
        /// Gets the children.
        /// </summary>
        /// <value>The children.</value>
        public Collection<LeftPaneModel> Children
        {
            get
            {
                return this.children;
            }
        }

        /// <summary>
        /// Gets or sets a value indicating whether this instance is category model.
        /// </summary>
        /// <value>
        /// 	<c>true</c> if this instance is category model; otherwise, <c>false</c>.
        /// </value>
        public bool IsCategoryModel
        {
            get
            {
                return isCategoryModel;
            }
            set
            {
                isCategoryModel = value;
            }
        }

        /// <summary>
        /// Gets or sets the version label.
        /// </summary>
        /// <value>The version label.</value>
        public string VersionLabel
        {
            get
            {
                return versionLabel;
            }
            set
            {
                versionLabel = value;
            }
        }

        /// <summary>
        /// Gets or sets the modified time.
        /// </summary>
        /// <value>The modified time.</value>
        public DateTime ModifiedTime
        {
            get
            {
                return modifiedTime;
            }
            set
            {
                modifiedTime = value;
            }
        }

        /// <summary>
        /// Gets or sets the label.
        /// </summary>
        /// <value>The label.</value>
        public override string Label
        {
            get
            {
                return string.IsNullOrEmpty(this.VersionLabel) ? this.Name : string.Format(CultureInfo.CurrentUICulture, "{0} ({1})", this.Name, this.VersionLabel);
            }
            set
            {
                base.Label = value;
            }
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="LeftPaneModel"/> class.
        /// </summary>
        public LeftPaneModel()
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="LeftPaneModel"/> class.
        /// </summary>
        /// <param name="category">The category.</param>
        /// <param name="currentUser">The current user.</param>
        public LeftPaneModel(Namespace category, User currentUser)
        {
            this.Name = category.Name;
            this.Label = (string.IsNullOrEmpty(category.Label)) ? this.Name : category.Label;
            this.Id = (category as IObject).ID;
            this.IsCategoryModel = true;

            //this.ItemIcon = BaseModel.CreateImage(@"../../Images/CategoriesHeader.png");

            if (currentUser != null)
            {
                List<LeftPaneModel> tempList = new List<LeftPaneModel>();
                foreach (Activity activity in category.Activitys)
                {
                    if (!activity.IsDeleted
                        && (activity.Security.Rights.AuthorWorkflow.Check(currentUser)
                            || activity.Security.Rights.RunWorkflow.Check(currentUser)))
                    {
                        if (!string.IsNullOrEmpty(activity.VersionLabel) || activity.IsLatestVersion())
                        {
                            tempList.Add(new LeftPaneModel(activity));
                        }
                    }
                }

                tempList.Sort(LeftPaneModel.LeftPaneModelComparer);
                tempList.ForEach(a => this.children.Add(a));

                foreach (Namespace ns in category.Children)
                {
                    this.Children.Add(new LeftPaneModel(ns, currentUser));
                }
            }
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="WorkflowModel"/> class.
        /// </summary>
        /// <param name="workflow">The workflow.</param>
        public LeftPaneModel(Activity workflow)
            : base(workflow)
        {
            this.IsCategoryModel = false;
            this.VersionLabel = workflow.VersionLabel;
            //this.ItemIcon = BaseModel.CreateImage(@"../../Images/WorkflowIcon.png");
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="CategoryModel"/> class.
        /// </summary>
        /// <param name="category">The category.</param>
        private LeftPaneModel(string categoryLabel, IEnumerable<Activity> activities)
        {
            this.Name = categoryLabel;
            this.Label = categoryLabel;
            this.IsCategoryModel = true;
            //this.ItemIcon = BaseModel.CreateImage(@"../../Images/CategoriesHeader.png");

            foreach (Activity activity in activities)
            {
                if (!activity.IsDeleted && (!string.IsNullOrEmpty(activity.VersionLabel) || activity.IsLatestVersion()))
                {
                    this.Children.Add(new LeftPaneModel(activity));
                }
            }
        }

        /// <summary>
        /// Generates the virtual category model.
        /// </summary>
        /// <param name="categoryName">Name of the category.</param>
        /// <param name="activities">The activities.</param>
        /// <returns></returns>
        public static LeftPaneModel GenerateVirtualCategoryModel(string categoryLabel, IEnumerable<Activity> activities)
        {
            return new LeftPaneModel(categoryLabel, activities);
        }

        /// <summary>
        /// Sorts the activity list based on workflow name and the modified time.
        /// Implementation of Icomparer object
        /// </summary>
        /// <param name="activityA">Activity</param>
        /// <param name="activityB">Activity</param>
        /// <returns></returns>
        public static int LeftPaneModelComparer(LeftPaneModel first, LeftPaneModel second)
        {
            int result = 0;
            string firstStringToCompare = first.Name;
            string secondStringToCompare = second.Name;
            int compareValue = string.Compare(firstStringToCompare, secondStringToCompare, StringComparison.OrdinalIgnoreCase);
            if (compareValue != 0)
            {
                result = compareValue > 0 ? 1 : -1;
            }
            else
            {
                compareValue = DateTime.Compare(first.ModifiedTime, second.ModifiedTime);
                result = compareValue > 0 ? -1 : 1;
            }
            return result;
        }

    }
}
